const fs = require('fs');
const https = require('https');
const express = require('express');
const { Server } = require('socket.io');
const cors = require('cors');
const { yh1, Chat, DeleteMark,fuanModel } = require('../model/db');


const app = express();

// 中间件设置
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: false }));

// HTTPS 服务器配置
const server = https.createServer({
  key: fs.readFileSync('./certs/192.168.43.82-key.pem'),
  cert: fs.readFileSync('./certs/192.168.43.82.pem')
}, app);

const io = new Server(server, {
  cors: { origin: '*' }
});

// 存储 id <-> socket.id 的映射
const userMap = new Map();
const users = {};

// 路由处理
app.get('/', (req, res) => {
  res.json({ message: 'WebRTC 信令服务器运行中' });
});

app.post('/shoc/add',async(req,res)=>{
    fuanModel.create(req.body)
    res.send({
        code:200,
        msg:"添加成功"
    })
})
app.post('/shoc/list',async(req,res)=>{
  console.log(123);
  
    let data = await fuanModel.find()
    res.send({
        data
    })
})
app.get('/shoc/del',async(req,res)=>{
    let {id} = req.query
    await fuanModel.deleteOne(id)
    res.send({
        code:200,
        msg:"删除成功"
    })
})
app.post('/shoc/update',async(req,res)=>{
    let {id} = req.body
    await fuanModel.updateOne({_id:id},req.body)
    res.send({
        code:200,
        msg:"修改成功"
    })
})
// 获取用户与其他人的最后一条消息
app.get('/dl', async (req, res) => {
  const { username } = req.query;
  if (!username) {
    return res.status(400).json({ code: 400, msg: '请提供用户名参数' });
  }

  try {
    // 1. 获取所有用户（除自己）
    const allUsers = await yh1.find({ name: { $ne: username } });

    // 2. 获取所有与该用户相关的会话的最后一条消息
    const sessions = await Chat.aggregate([
      {
        $match: {
          $or: [
            { from: username },
            { to: username }
          ]
        }
      },
      {
        $addFields: {
          sessionKey: {
            $cond: [
              { $gt: ["$from", "$to"] },
              { $concat: ["$to", "_", "$from"] },
              { $concat: ["$from", "_", "$to"] }
            ]
          }
        }
      },
      { $sort: { timestamp: -1 } },
      {
        $group: {
          _id: "$sessionKey",
          lastMsg: { $first: "$message" },
          time: { $first: "$timestamp" },
          from: { $first: "$from" },
          to: { $first: "$to" }
        }
      },
      { $sort: { time: -1 } }
    ]);

    // 3. 构建一个映射，方便查找
    const sessionMap = {};
    sessions.forEach(s => {
      // 找到对方名字
      const other = s.from === username ? s.to : s.from;
      sessionMap[other] = s;
    });

    // 4. 对所有用户都生成一条数据
    const result = allUsers.map(u => {
      if (sessionMap[u.name]) {
        return sessionMap[u.name];
      } else {
        return {
          _id: [username, u.name].sort().join('_'),
          lastMsg: null,
          time: null,
          from: username,
          to: u.name
        };
      }
    });

    console.log('sessions', sessions);
    console.log('result', result);

    return res.send({
      code: 200,
      data: result
    });
  } catch (err) {
    if (!res.headersSent) {
      return res.status(500).json({ code: 500, msg: '服务器错误' });
    }
  }
});

// 用户登录
app.post('/login', async (req, res) => {
  const { name, password } = req.body;
  try {
    const user = await yh1.findOne({ name, password });
    if (user) {
      res.send({ code: 200 });
    } else {
      res.send({ code: 201 });
    }
  } catch (err) {
    res.status(500).json({ code: 500, msg: '服务器错误' });
  }
});

// 保存聊天记录
app.post('/chat', async (req, res) => {
  const { from, to, message } = req.body;
  if (!from || !to || !message) {
    return res.status(400).json({ code: 400, msg: '参数不完整' });
  }
  try {
    const chat = new Chat({ from, to, message, timestamp: new Date() });
    await chat.save();
    
    // 实时发送消息给在线用户
    const fromSocketId = [...userMap.entries()].find(([, uid]) => uid === from)?.[0];
    const toSocketId = [...userMap.entries()].find(([, uid]) => uid === to)?.[0];
    if (fromSocketId) {
      console.log('推送给自己', from);
      io.to(fromSocketId).emit('new-message', { from, message, timestamp: new Date() });
    }
    if (toSocketId && toSocketId !== fromSocketId) {
      console.log('推送给对方', to);
      io.to(toSocketId).emit('new-message', { from, message, timestamp: new Date() });
    }
    
    res.json({ code: 200, msg: '保存成功' });
  } catch (err) {
    res.status(500).json({ code: 500, msg: '服务器错误' });
  }
});

// 获取聊天记录
app.get('/chat', async (req, res) => {
  const { user1, user2 } = req.query;
  if (!user1 || !user2) {
    return res.status(400).json({ code: 400, msg: '参数不完整' });
  }
  try {
    // 查找 user1 对 user2 的删除标记
    const mark = await DeleteMark.findOne({ user: user1, peer: user2 });
    let filter = {
      $or: [
        { from: user1, to: user2 },
        { from: user2, to: user1 }
      ]
    };
    if (mark && mark.deletedBefore) {
      filter.timestamp = { $gt: mark.deletedBefore };
    }
    const history = await Chat.find(filter).sort({ timestamp: 1 });
    res.json({ code: 200, data: history });
  } catch (err) {
    res.status(500).json({ code: 500, msg: '服务器错误' });
  }
});

// 标记消息为已读
app.put('/chat/mark-read', async (req, res) => {
  const { user1, user2 } = req.query;
  if (!user1 || !user2) {
    return res.status(400).json({ code: 400, msg: '参数不完整' });
  }
  try {
    await Chat.updateMany(
      { from: user2, to: user1, read: false },
      { $set: { read: true } }
    );
    res.json({ code: 200, msg: '已标记为已读' });
  } catch (err) {
    res.status(500).json({ code: 500, msg: '服务器错误' });
  }
});

// 获取每个会话的未读消息数
app.get('/chat/unread', async (req, res) => {
  const { user } = req.query;
  if (!user) {
    return res.status(400).json({ code: 400, msg: '参数不完整' });
  }
  try {
    const result = await Chat.aggregate([
      { $match: { to: user, read: false } },
      { $group: { _id: '$from', count: { $sum: 1 } } }
    ]);
    const unreadMap = {};
    result.forEach(item => {
      unreadMap[item._id] = item.count;
    });
    res.json({ code: 200, data: unreadMap });
  } catch (err) {
    res.status(500).json({ code: 500, msg: '服务器错误' });
  }
});

// 清除两个人的聊天记录
app.delete('/chat', async (req, res) => {
  const { user1, user2 } = req.query;
  if (!user1 || !user2) {
    return res.status(400).json({ code: 400, msg: '参数不完整' });
  }
  try {
    await Chat.deleteMany({
      $or: [
        { from: user1, to: user2 },
        { from: user2, to: user1 }
      ]
    });
    res.json({ code: 200, msg: '聊天记录已清除' });
  } catch (err) {
    res.status(500).json({ code: 500, msg: '服务器错误' });
  }
});

// 清除聊天记录（软删除）
app.post('/chat/clear', async (req, res) => {
  const { user1, user2 } = req.body;
  if (!user1 || !user2) {
    return res.status(400).json({ code: 400, msg: '参数不完整' });
  }
  try {
    await DeleteMark.findOneAndUpdate(
      { user: user1, peer: user2 },
      { deletedBefore: new Date() },
      { upsert: true }
    );
    res.json({ code: 200, msg: '已清除' });
  } catch (err) {
    res.status(500).json({ code: 500, msg: '服务器错误' });
  }
});

// 发送消息
app.post('/chat/send', async (req, res) => {
  const { from, to, message } = req.body;
  if (!from || !to || !message) {
    return res.status(400).json({ code: 400, msg: '参数不完整' });
  }
  try {
    const chat = new Chat({
      from,
      to,
      message,
      timestamp: new Date()
    });
    await chat.save();
    
    // 实时发送消息给在线用户
    const fromSocketId = [...userMap.entries()].find(([, uid]) => uid === from)?.[0];
    const toSocketId = [...userMap.entries()].find(([, uid]) => uid === to)?.[0];
    if (fromSocketId) {
      console.log('推送给自己', from);
      io.to(fromSocketId).emit('new-message', { from, message, timestamp: new Date() });
    }
    if (toSocketId && toSocketId !== fromSocketId) {
      console.log('推送给对方', to);
      io.to(toSocketId).emit('new-message', { from, message, timestamp: new Date() });
    }
    
    res.json({ code: 200, msg: '发送成功' });
  } catch (err) {
    res.status(500).json({ code: 500, msg: '服务器错误' });
  }
});

// WebSocket 连接处理
io.on('connection', (socket) => {
  console.log(`用户连接: ${socket.id}`);
  
  // 用户登录
  socket.on('login', ({ id }) => {
    if (!id) {
      socket.emit('login-fail', 'ID不能为空');
      return;
    }
    // 踢掉所有已绑定该ID的socket
    for (const [sid, uid] of userMap.entries()) {
      if (uid === id) {
        io.sockets.sockets.get(sid)?.disconnect(true);
        userMap.delete(sid);
      }
    }
    userMap.set(socket.id, id);
    users[socket.id] = { id };
    socket.emit('login-success', { id });
    console.log(`用户登录: ${id}`);
  });

  // 用户加入房间
  socket.on('join', roomId => {
    socket.join(roomId);
    if (users[socket.id]) {
      users[socket.id].roomId = roomId;
    }
    console.log(`用户 ${socket.id} 加入房间 ${roomId}`);
  });

  // WebRTC 呼叫
  socket.on('call-user', ({ userToCall, signalData, from }) => {
    console.log(`收到呼叫: from=${from} to=${userToCall}`);
    const targetSocketId = [...userMap.entries()].find(([, uid]) => uid === userToCall)?.[0];
    if (targetSocketId) {
      io.to(targetSocketId).emit('call-made', { from, signal: signalData });
    }
  });

  // 接听 WebRTC 呼叫
  socket.on('accept-call', ({ to, signal }) => {
    const targetSocketId = [...userMap.entries()].find(([, uid]) => uid === to)?.[0];
    if (targetSocketId) {
      io.to(targetSocketId).emit('call-accepted', signal);
    }
  });

  // 挂断/拒绝来电
  socket.on('reject-call', ({ to }) => {
    const targetSocketId = [...userMap.entries()].find(([, uid]) => uid === to)?.[0];
    if (targetSocketId) {
      io.to(targetSocketId).emit('call-rejected');
    }
  });

  // 结束通话
  socket.on('endCall', roomId => {
    socket.to(roomId).emit('callEnded');
  });

  // 断开连接
  socket.on('disconnect', () => {
    const id = userMap.get(socket.id);
    const user = users[socket.id];
    
    if (user && user.roomId) {
      socket.to(user.roomId).emit('callEnded');
    }
    
    // 删除所有绑定该 id 的 socket
    for (const [sid, uid] of userMap.entries()) {
      if (uid === id) userMap.delete(sid);
    }
    
    delete users[socket.id];
    console.log(`用户离线: ${id}`);
  });
});

// 启动服务器
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
  console.log(`综合服务器已启动，端口 ${PORT} (HTTPS)`);
  console.log('功能包括: WebRTC 信令、聊天、用户管理');
});


module.exports = { app, server, io };